library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity tb_counter_8bit is
end tb_counter_8bit;

architecture BEH of tb_counter_8bit is
    component counter_8bit
        Port ( clk : in  STD_LOGIC;
               E : in  STD_LOGIC;
               WE : in  STD_LOGIC;
               Q : in  UNSIGNED(7 downto 0);
               D : out  UNSIGNED(7 downto 0));
    end component;

    signal clk_tb : STD_LOGIC := '0';
    signal E_tb : STD_LOGIC := '0';
    signal WE_tb : STD_LOGIC := '0';
    signal Q_tb : UNSIGNED(7 downto 0) := (others => '0');
    signal D_tb : UNSIGNED(7 downto 0);

    constant clk_period : time := 10 ns;

begin
    uut: counter_8bit port map (
        clk => clk_tb,
        E => E_tb,
        WE => WE_tb,
        Q => Q_tb,
        D => D_tb
    );

    clk_process: process
    begin
        clk_tb <= '0';
        wait for clk_period/2;
        clk_tb <= '1';
        wait for clk_period/2;
    end process;

    stim_process: process
    begin
        -- Initialize
        E_tb <= '0';
        WE_tb <= '0';
        Q_tb <= (others => '0');

        -- Enable and load value
        wait for 20 ns;
        E_tb <= '1';
        WE_tb <= '1';
        Q_tb <= "00001001";
        wait for 10 ns;
        assert D_tb = "00001001" report "Error: Loaded value is incorrect";

        -- Increment
        WE_tb <= '0';
        wait for 10 ns;
        assert D_tb = "00001010" report "Error: Increment failed";

        -- Disable
        E_tb <= '0';
        wait for 10 ns;

        -- Enable and increment again
        E_tb <= '1';
        wait for 10 ns;
        assert D_tb = "00001011" report "Error: Increment failed after re-enable";

        -- Load new value
        WE_tb <= '1';
        Q_tb <= "00001111";
        wait for 10 ns;
        assert D_tb = "00001111" report "Error: Loaded value is incorrect";

        -- Finish
        wait;
    end process;
end BEH;